package retrofit2.harmony.ui.slice;

import com.cjj.MaterialRefreshLayout;
import com.cjj.MaterialRefreshListener;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Consumer;
import me.drakeet.multitype.MultiTypeAdapter;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.Component;
import ohos.agp.components.ListContainer;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.harmony.Constant;
import retrofit2.harmony.MyApplication;
import retrofit2.harmony.ResourceTable;
import retrofit2.harmony.WebAbility;
import retrofit2.harmony.model.HomeArticleModel;
import retrofit2.harmony.model.base.HttpModel;
import retrofit2.harmony.model.base.PageModel;
import retrofit2.harmony.ui.itemprovider.HomeArticleItemViewBinder;
import retrofit2.harmony.util.ToastUtil;
import retrofit2.harmony.util.rx.RxLifecycleUtil;
import retrofit2.harmony.util.rx.RxSchedulerUtil;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

/**
 * 首页
 */
public class HomeSlice extends AbilitySlice {
    public static HomeSlice newInstance() {
        return new HomeSlice();
    }

    private MaterialRefreshLayout vRefreshLayout;
    private ListContainer vList;
    private final List<HomeArticleModel> mListData = new ArrayList<>();
    private final MultiTypeAdapter mListAdapter = new MultiTypeAdapter(mListData);

    /**
     * 当前页码
     */
    private int mCurrentPage;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_slice_home);
        findView();
        bindView();
        setData();
    }

    private void findView() {
        vRefreshLayout = (MaterialRefreshLayout) findComponentById(ResourceTable.Id_refresh_layout);
        vList = (ListContainer) findComponentById(ResourceTable.Id_list);
    }

    private void bindView() {
        //设置适配器
        vList.setItemProvider(mListAdapter);
        //注册条目类型
        mListAdapter.register(HomeArticleModel.class, new HomeArticleItemViewBinder());
        //设置点击事件
        vList.setItemClickedListener(new ListContainer.ItemClickedListener() {
            @Override
            public void onItemClicked(ListContainer listContainer, Component component, int position, long id) {
                //点击跳转到浏览器
                HomeArticleModel itemModel = mListData.get(position);
                String link = itemModel.getLink();
                Operation operation = new Intent.OperationBuilder()
                        .withDeviceId("")
                        .withBundleName(getBundleName())
                        .withAbilityName(WebAbility.class)
                        .build();
                Intent intent = new Intent();
                intent.setOperation(operation);
                intent.setParam(Constant.KEY_WEB_LINK, link);
                startAbility(intent);
            }
        });
        //允许加载更多
        vRefreshLayout.setLoadMore(true);
        //下拉刷新和加载更多监听
        vRefreshLayout.setMaterialRefreshListener(new MaterialRefreshListener() {
            @Override
            public void onRefresh(MaterialRefreshLayout materialRefreshLayout) {
                refresh();
            }

            @Override
            public void onRefreshLoadMore(MaterialRefreshLayout materialRefreshLayout) {
                super.onRefreshLoadMore(materialRefreshLayout);
                loadMore();
            }
        });
    }

    private void setData() {
        refresh();
    }

    private void refresh() {
        this.mCurrentPage = 0;
        getHomeArticle(mCurrentPage, true);
    }

    private void loadMore() {
        int nextPage = this.mCurrentPage + 1;
        getHomeArticle(nextPage, false);
    }

    /**
     * RxJava，获取首页文章列表
     */
    private void getHomeArticle(int page, boolean isRefresh) {
        MyApplication application = MyApplication.getInstance();
        application.getWanAndroid().getHomeArticle(page)
                //IO切换到主线程
                .compose(RxSchedulerUtil.ioToMain())
                //生命周期绑定
                .as(RxLifecycleUtil.bindLifecycle(getLifecycle()))
                .subscribe(new Consumer<HttpModel<PageModel<HomeArticleModel>>>() {
                    @Override
                    public void accept(@NonNull HttpModel<PageModel<HomeArticleModel>> model) throws Exception {
                        processResult(model, isRefresh);
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(@NonNull Throwable throwable) throws Exception {
                        throwable.printStackTrace();
                        ToastUtil.toast(getContext(), "请求失败：" + throwable.getMessage());
                    }
                });
    }

    /**
     * Retrofit Call，获取首页文章列表，没有添加转换器，需要自己做Json数据和模型的转换
     */
    private void getHomeArticleByCall(int page, boolean isRefresh) {
        MyApplication application = MyApplication.getInstance();
        application.getWanAndroid().getHomeArticleByCall(page)
                .enqueue(new Callback<ResponseBody>() {
                    @Override
                    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                        try {
                            if (response.body() == null) {
                                ToastUtil.toast(getContext(), "请求失败：body为空");
                            }
                            String json = response.body().string();
                            Gson gson = new Gson();
                            Type type = new TypeToken<HttpModel<PageModel<HomeArticleModel>>>() {
                            }.getType();
                            HttpModel<PageModel<HomeArticleModel>> model = gson.fromJson(json, type);
                            processResult(model, isRefresh);
                        } catch (IOException e) {
                            e.printStackTrace();
                            ToastUtil.toast(getContext(), "请求失败：" + e.getMessage());
                        }
                    }

                    @Override
                    public void onFailure(Call<ResponseBody> call, Throwable throwable) {
                        ToastUtil.toast(getContext(), "请求失败：" + throwable.getMessage());
                    }
                });
    }

    /**
     * 添加了转换器，可以会通过转换器自动把Json转换为模型
     */
    private void getHomeArticleByCallWithConverter(int page, boolean isRefresh) {
        MyApplication application = MyApplication.getInstance();
        application.getWanAndroid().getHomeArticleByCallWithConverter(page)
                .enqueue(new Callback<HttpModel<PageModel<HomeArticleModel>>>() {
                    @Override
                    public void onResponse(Call<HttpModel<PageModel<HomeArticleModel>>> call,
                                           Response<HttpModel<PageModel<HomeArticleModel>>> response) {
                        processResult(response.body(), isRefresh);
                    }

                    @Override
                    public void onFailure(Call<HttpModel<PageModel<HomeArticleModel>>> call, Throwable throwable) {
                        ToastUtil.toast(getContext(), "请求失败：" + throwable.getMessage());
                    }
                });
    }

    private void processResult(HttpModel<PageModel<HomeArticleModel>> model, Boolean isRefresh) {
        if (model == null) {
            return;
        }
        PageModel<HomeArticleModel> pageModel = model.getData();
        if (pageModel == null) {
            return;
        }
        List<HomeArticleModel> list;
        if (pageModel.getDatas() != null) {
            list = pageModel.getDatas();
        } else {
            list = new ArrayList<>();
        }
        //是否有下一页
        boolean hasMore = !pageModel.isOver();
        if (!hasMore) {
            ToastUtil.toast(getContext(), "没有更多啦");
        }
        //更新当前页码
        mCurrentPage = pageModel.getOffset();
        if (isRefresh) {
            mListData.clear();
            vRefreshLayout.finishRefreshing();
        } else {
            vRefreshLayout.finishRefreshLoadMore();
        }
        //更新列表
        mListData.addAll(list);
        mListAdapter.notifyDataChanged();
    }
}